<template>
  <el-dialog :title="title" v-model="visible" class="dialog-md" append-to-body @close="visible = false">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="100px" v-loading="loading">
      <el-form-item label="上级菜单" prop="parent_id">
        <el-tree-select
          v-model="form.parent_id"
          :data="menuOptions"
          :props="{ value: 'id', label: 'name', children: 'children' }"
          value-key="id"
          placeholder="选择上级菜单"
          check-strictly />
      </el-form-item>
      <el-form-item label="菜单类型" prop="type">
        <el-radio-group v-model="form.type">
          <el-radio value="M">目录</el-radio>
          <el-radio value="C">菜单</el-radio>
          <el-radio value="F">按钮</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单图标" prop="icon" v-if="form.type !== 'F'">
        <el-popover placement="bottom-start" :width="540" trigger="click">
          <template #reference>
            <el-input v-model="form.icon" placeholder="点击选择图标" clearable>
              <template #prefix>
                <icon-show :icon="form.icon || 'search'" class="el-input__icon" style="color: #555" />
              </template>
            </el-input>
          </template>
          <icon-select @selected="iconSelected" :active-icon="form.icon" />
        </el-popover>
      </el-form-item>
      <el-row>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入菜单名称" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="显示排序" prop="list_sort">
            <el-input-number v-model="form.list_sort" controls-position="right" :min="0" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'F'">
          <el-form-item prop="is_external">
            <template #label>
              <span>
                <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                是否外链
              </span>
            </template>
            <el-radio-group v-model="form.is_external">
              <el-radio value="1">是</el-radio>
              <el-radio value="0">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'F'">
          <el-form-item prop="url" :rules="[{ required: true, message: '路由地址不能为空' }]">
            <template #label>
              <span>
                <el-tooltip
                  content="默认不填则和路由地址相同：如地址为：`user`，则名称为`User`（注意：因为router会删除名称相同路由，为避免名字的冲突，特殊情况下请自定义，保证唯一性）"
                  placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                路由地址
              </span>
            </template>
            <el-input v-model="form.url" placeholder="请输入路由地址" maxlength="250" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="component">
            <template #label>
              <span>
                <el-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                组件路径
              </span>
            </template>
            <el-input v-model="form.component" placeholder="请输入组件路径" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'M'">
          <el-form-item prop="perms">
            <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="128" />
            <template #label>
              <span>
                <el-tooltip
                  content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
                  placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                权限字符
              </span>
            </template>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="query">
            <template #label>
              <span>
                <el-tooltip content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`' placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                路由参数
              </span>
            </template>
            <el-input v-model="form.query" placeholder="请输入路由参数" maxlength="250" />
          </el-form-item>
        </el-col>

        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="is_cache">
            <template #label>
              <span>
                <el-tooltip content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                是否缓存
              </span>
            </template>
            <el-radio-group v-model="form.is_cache">
              <el-radio value="1">缓存</el-radio>
              <el-radio value="0">不缓存</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type != 'F'">
          <el-form-item prop="is_visible">
            <template #label>
              <span>
                <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                显示状态
              </span>
            </template>
            <el-radio-group v-model="form.is_visible">
              <el-radio v-for="dict in sys_show_hide" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item prop="status">
            <template #label>
              <span>
                <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                菜单状态
              </span>
            </template>
            <el-radio-group v-model="form.status">
              <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{
                dict.label
              }}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div class="dialog-footer">
      <el-button class="medium" type="primary" :loading="submitting" :disabled="loading" @click="handleSubmit"
        >确 定</el-button
      >
      <el-button class="medium" @click="visible = false">取 消</el-button>
    </div>
  </el-dialog>
</template>
<script setup name="MenuForm">
  import { infoMenuApi, addMenuApi, editMenuApi, selectMenuApi } from '@/api/system/menu'
  import IconSelect from '@/components/widgets/IconSelect'
  import IconShow from '@/components/widgets/IconShow'

  const props = defineProps({ row: Object, moduleName: String })
  const visible = defineModel()
  const { proxy } = getCurrentInstance()

  const form = ref({
    name: undefined,
    parent_id: undefined,
    type: 'M',
    perms: undefined,
    icon: undefined,
    url: undefined,
    query: undefined,
    component: undefined,
    is_external: '0',
    is_cache: '1',
    is_visible: '1',
    status: '1',
    list_sort: 0,
    remark: undefined
  })
  const rules = ref({
    parent_id: [{ required: true, message: '请选择上级菜单', trigger: 'change' }],
    type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }],
    name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
    list_sort: [{ required: true, message: '顺序不能为空', trigger: 'blur' }],
    status: [{ required: true, message: '请选择菜单状态', trigger: 'blur' }]
  })
  const { sys_show_hide, sys_normal_disable } = proxy.useDict('sys_show_hide', 'sys_normal_disable')

  // 初始加载
  const title = ref('')
  const loading = ref(false)
  onMounted(async () => {
    loading.value = true
    form.value.id = props.row?.id || undefined
    if (form.value.id) {
      title.value = '编辑' + props.moduleName
      await getRowData()
    } else {
      title.value = '新增' + props.moduleName
      form.value.parent_id = props.row?.parent_id || 0
    }
    await getTreeSelect()
    loading.value = false
  })

  // 获取信息
  async function getRowData() {
    try {
      const { info } = await infoMenuApi(form.value.id)
      form.value = proxy.dataToForm(form.value, info)
    } catch (error) {
      visible.value = false
    }
  }

  // 提交表单
  const submitting = ref(false)
  const emit = defineEmits(['submit'])
  const formRef = useTemplateRef('formRef')
  async function handleSubmit() {
    try {
      const valid = await formRef.value.validate()
      if (!valid) return
    } catch (error) {
      return
    }
    if (submitting.value) return
    submitting.value = true
    try {
      await proxy.$modal.confirm('确定提交表单数据？')
      if (form.value.id) {
        await editMenuApi(form.value)
      } else {
        await addMenuApi(form.value)
      }
      emit('submit')
      proxy.$modal.msgSuccess('操作成功')
      visible.value = false
    } catch (e) {
      submitting.value = false
    }
  }

  // 图标选择
  function iconSelected(icon) {
    form.value.icon = icon
  }

  // 获取菜单树
  const menuOptions = ref([])
  async function getTreeSelect() {
    try {
      const { list } = await selectMenuApi()
      const menu = { id: 0, name: '主类目', children: [] }
      menu.children = proxy.listToTree(list)
      menuOptions.value = [menu]
    } catch (e) {}
  }
</script>
